package com.laker.autotest.webui.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.impl.driver.Driver;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static java.util.Arrays.asList;

@Slf4j
public class PlaywrightUtil {

    private PlaywrightUtil() {
        // 私有构造
    }

    public static Playwright initPlaywright() {
        Playwright.CreateOptions createOptions = new Playwright.CreateOptions();
        Map<String, String> env = new HashMap<>();
        // 跳过浏览器下载
        env.put("PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD", "1");
        env.put("PLAYWRIGHT_DOWNLOAD_HOST", "https://registry.npmmirror.com/-/binary/playwright");
        createOptions.setEnv(env);
        return Playwright.create(createOptions);
    }

    @SneakyThrows
    public static void command(String[] args) {
        Map<String, String> env = new HashMap<>();
        env.put("PLAYWRIGHT_DOWNLOAD_HOST", "https://registry.npmmirror.com/-/binary/playwright");
        Driver driver = Driver.ensureDriverInstalled(env, false);
        ProcessBuilder pb = driver.createProcessBuilder();
        pb.command().addAll(asList(args));
        String version = Playwright.class.getPackage().getImplementationVersion();
        if (version != null) {
            pb.environment().put("PW_CLI_DISPLAY_VERSION", version);
        }
        pb.inheritIO();
        Process process = pb.start();
        System.exit(process.waitFor());
    }

    /**
     * @param browserName 浏览器名称 eg: chromium, firefox, webkit
     */
    @SneakyThrows
    public static void installBrowser(String browserName) {
        String isSkip = System.getenv("PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD");
        if (StrUtil.equals(isSkip, "1")) {
            log.warn(">>>>>>>>>>>>>>>> Skipping Playwright Browser Installation, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD is set to 1");
            return;
        }
        String version = Playwright.class.getPackage().getImplementationVersion();
        String userHome = System.getProperty("user.home");
        String path = userHome + File.separator + "easy-autotest";
        log.info(">>>>>>>>>>>>>>>> Playwright Browser Install Path: {}", path);
        String fileName = version + "-" + browserName + ".easy";
        log.info(">>>>>>>>>>>>>>>> Playwright Browser Install File: {}", fileName);
        if (FileUtil.exist(path + "/" + fileName)) {
            log.warn(">>>>>>>>>>>>>>>> {} Browser Already Installed. Skip.", browserName);
            return;
        }

        Map<String, String> env = new HashMap<>();
        // 默认情况下，Playwright 从 Microsoft 的 CDN 下载浏览器
        env.put("PLAYWRIGHT_DOWNLOAD_HOST", "https://registry.npmmirror.com/-/binary/playwright");
        // 配置通过代理服务器下载浏览器
//        env.put("HTTPS_PROXY", "https://192.0.2.1");
        // 如果您的网络连接到 Playwright 浏览器存档的速度很慢，您可以通过设置 PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT 来增加连接超时。
        env.put("PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT", "120000");
        // 过时的浏览器删除
        // Playwright 会跟踪使用其浏览器的客户端。当没有更多客户端需要特定版本的浏览器时，将从系统中删除该版本。这样，您就可以安全地使用不同版本的 Playwright 实例，同时，您不会为不再使用的浏览器浪费磁盘空间。
        // 要选择退出未使用的浏览器删除，您可以设置
//        env.put("PLAYWRIGHT_SKIP_BROWSER_GC", "1");
        Driver driver = Driver.ensureDriverInstalled(env, false);
        ProcessBuilder pb = driver.createProcessBuilder();
        pb.command().addAll(asList("install", "--with-deps", browserName));
        if (version != null) {
            pb.environment().put("PW_CLI_DISPLAY_VERSION", version);
        }
        pb.inheritIO();
        Process p = pb.start();
        boolean result = p.waitFor(10L, TimeUnit.MINUTES);
        if (!result) {
            p.destroy();
            throw new RuntimeException("Timed out waiting for browsers to install");
        } else if (p.exitValue() != 0) {
            throw new RuntimeException("Failed to install browsers, exit code: " + p.exitValue());
        }
        FileUtil.mkdir(path);
        boolean success = FileUtil.newFile(path + "/" + fileName).createNewFile();
        log.info(">>>>>>>>>>>>>>>> {} Browser installation completed, result:{}", browserName, success);
    }

}
